﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data.Entity.Validation;
using System.IO;
using System.Linq;
using System.Text;
using Wicresoft.Logger.Entity;

namespace Wicresoft.Logger
{
    public static class Log
    {
        private static LogContext logDb = new LogContext();
        private static LogLevel level = (LogLevel)Enum.Parse(typeof(LogLevel),
            ConfigurationManager.AppSettings["LogLevel"]);

        /// <summary>
        /// 提供集中的日志记录方式，日志将被写入预设的数据库表
        /// </summary>
        /// <param name="task">发生日志的任务</param>
        /// <param name="message">日志内容</param>
        /// <param name="e">异常信息，可以为空</param>
        public static void Info(string task, string message, params object[] objs)
        {
            if ((level & LogLevel.Info) != 0)
            {
                var entity = new Entity.Log
                {
                    CreatedTime = DateTime.Now,
                    Verb = "Info",
                    TaskName = task,
                    Message = string.Format(message, objs),
                };

                Push(entity);
            }
        }

        public static void Debug(string task, string message, params object[] objs)
        {
            if ((level & LogLevel.Debug) != 0)
            {
                var entity = new Entity.Log
                {
                    CreatedTime = DateTime.Now,
                    Verb = "Debug",
                    TaskName = task,
                    Message = string.Format(message, objs),
                };

                Push(entity);
            }
        }

        public static void Error(string task, string message, params object[] objs)
        {
            if ((level & LogLevel.Error) != 0)
            {
                var entity = new Entity.Log
                {
                    CreatedTime = DateTime.Now,
                    Verb = "Error",
                    TaskName = task,
                    Message = string.Format(message, objs),
                };

                Push(entity);
            }
        }

        public static void Exception(string task, Exception e)
        {
            if ((level & LogLevel.Exception) != 0)
            {
                var entity = new Entity.Log
                {
                    CreatedTime = DateTime.Now,
                    Verb = "Exception",
                    TaskName = task,
                    Message = e.Message,
                    Exception = e.ToString(),
                };

                Push(entity);
            }
        }

        private static void Push(Entity.Log entity)
        {
            lock (logDb)
            {
                try
                {
                    logDb.Logs.Add(entity);
                    logDb.SaveChanges();
                }
                catch (Exception e)
                {
                    File.AppendAllText("system.log", String.Format("[{0}] Write log failed, reason: {1}{2}", DateTime.Now, e.Message, Environment.NewLine));

                    File.AppendAllText("system.log", String.Format("\tVerb: {0}{1}", entity.Verb, Environment.NewLine));
                    File.AppendAllText("system.log", String.Format("\tTaskName: {0}{1}", entity.TaskName, Environment.NewLine));
                    File.AppendAllText("system.log", String.Format("\tMessage: {0}{1}", entity.Message, Environment.NewLine));
                    File.AppendAllText("system.log", String.Format("\tException: {0}{1}", entity.Exception, Environment.NewLine));
                }
            }
        }
    }
}
